from datetime import timedelta
from fastapi import APIRouter, HTTPException
from utils.regions import list_regions
from utils.funcs import calculate_distance
from api.dep import auth_dep, uow_dep
from api.schemas import FlyInfo
from api.dto import generate_sqlalchemy_dto, RegionDTO, EntityRegionDTO

router = APIRouter(prefix="/regions", tags=["regions"])


@router.get("/get_region/{region_id}")
async def get_region(region_id: int, token=auth_dep, uow=uow_dep):
    await uow.users.check_auth_and_get(token)

    region = await uow.regions.select_by_id(region_id)

    if region is None:
        raise HTTPException(status_code=404,
                            detail="Регион не найден")

    e_region = list_regions[region_id]

    dto_region = generate_sqlalchemy_dto(RegionDTO, region)
    dto_e_region = generate_sqlalchemy_dto(EntityRegionDTO, e_region)

    return dto_region | dto_e_region


@router.post("/fly")
async def fly(info: FlyInfo, token=auth_dep, uow=uow_dep):
    user = await uow.users.check_auth_and_get(token)

    if info.region_id >= len(list_regions):
        raise HTTPException(status_code=404,
                            detail="Регион не найден")

    if user.residence == info.region_id:
        raise HTTPException(status_code=400,
                            detail="Нельзя полететь в свой же регион")

    if await uow.flights.exists(user.id):
        raise HTTPException(status_code=400,
                            detail="Вы уже в полёте")

    arrival = list_regions[user.residence]
    dispatch = list_regions[info.region_id]

    dist = calculate_distance(arrival, dispatch)
    price = dist
    time = timedelta(seconds=dist)

    if user.cash < price:
        raise HTTPException(status_code=400,
                            detail="Недостаточно денег")

    await uow.users.remove_cash(user.id, price)
    await uow.flights.insert(user.id, info.region_id, time)
    return {"time": time}
